package namensdienst;

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.net.Socket;

import mware_lib.NameService;
import mware_lib.RemoteException;
import mware_lib.SkControl;
import mware_lib.communication.messRebind;

public class NameServiceData extends NameService {
	private String host;
	private int port;
	private Socket socket;
	//private static SkControl skelControl=new SkControl();
	
	public NameServiceData(String host, int port)
	{
		this.host = host;
		this.port = port;
	}

	@Override
	public void rebind(Object servant, String name) throws RemoteException {
		Class <?> proxy=null;
		Object oReceived = null;
		try {
			proxy = (Class<?>) (servant.getClass().getSuperclass()).getMethod("getProxyClass").invoke(null,(Object [])null);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(proxy == null)
		{
			System.err.println("mware_lib.NameServiceData: the class is unknown");
		}
		else
		{
			//creation of the message to send
			messRebind toSend = new messRebind(proxy, name,host,SkControl.skPort,proxy,"rebind");
			try {
					socket = new Socket(host,port);
					ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
					ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
					out.writeObject(toSend);
					oReceived = in.readObject();
					in.close();
					out.close();
					socket.close();
				} catch (Exception e) {
					throw new RemoteException("Problem when contacting the name service server");
			}
			if(oReceived != null && !(oReceived instanceof Exception))
			{
				SkControl.newSkeleton(name, servant);
			}
			else
				throw new RemoteException("Problem when received the answer from the name service server");
		}

	}

	@Override
	public Object resolve(String name) throws RemoteException {
		messRebind toSend = new messRebind(name, "resolve",null);
		
		Object received=null;
		try {
			
			socket = new Socket(host,port);
			ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
			ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
			out.writeObject(toSend);
			received = in.readObject();
			in.close();
			out.close();
			socket.close();
			if (received !=null && received instanceof messRebind)
			{
				messRebind mRbd=(messRebind) received;
				try {
					return mRbd.result.getConstructor(String.class, Integer.class, 
							String.class).newInstance(mRbd.getHost(), mRbd.getPort(), mRbd.getName());
				}catch (Exception e){
					throw new RemoteException("Problem when contacting the name service server " +
							"(problem with getConstructor");
				}
			}
			else {
				throw new RemoteException();
			}
		} catch (Exception e) {
			throw new RemoteException("Problem when contacting the name service server");
		}
	}
}
